import { ref } from 'vue'

/**
 * 复制功能的 composable 函数
 * 提供复制文本到剪贴板的功能，包括现代 API 和降级方案
 * 同时管理 toast 提示的显示状态和用户友好的错误处理
 */
export function useCopy() {
  const showToast = ref(false)
  const toastMessage = ref('复制成功！')
  const toastType = ref('success') // 'success', 'error', 'warning', 'info'
  const isRetrying = ref(false)
  const lastCopyAttempt = ref(null)

  /**
   * 显示 toast 提示
   * @param {string} message - 要显示的消息
   * @param {number} duration - 显示持续时间（毫秒）
   * @param {string} type - 提示类型 ('success', 'error', 'warning', 'info')
   */
  const showToastMessage = (message = '复制成功！', duration = 2000, type = 'success') => {
    toastMessage.value = message
    toastType.value = type
    showToast.value = true
    
    // 错误类型的提示显示时间更长
    const actualDuration = type === 'error' ? Math.max(duration, 3000) : duration
    
    setTimeout(() => {
      showToast.value = false
    }, actualDuration)
  }

  /**
   * 使用现代 Clipboard API 复制文本
   * @param {string} text - 要复制的文本
   * @returns {Promise<{success: boolean, error?: string}>} - 复制结果和错误信息
   */
  const copyWithClipboardAPI = async (text) => {
    try {
      await navigator.clipboard.writeText(text)
      return { success: true }
    } catch (err) {
      console.error('Clipboard API 复制失败:', err)
      
      // 分析错误类型
      let errorType = 'unknown'
      if (err.name === 'NotAllowedError') {
        errorType = 'permission'
      } else if (err.name === 'NotSupportedError') {
        errorType = 'unsupported'
      } else if (err.name === 'DataError') {
        errorType = 'data'
      }
      
      return { success: false, error: errorType, originalError: err }
    }
  }

  /**
   * 降级方案：使用 document.execCommand 复制文本
   * @param {string} text - 要复制的文本
   * @returns {Object} - 复制结果和错误信息
   */
  const fallbackCopyTextToClipboard = (text) => {
    const textArea = document.createElement('textarea')
    textArea.value = text
    textArea.style.top = '0'
    textArea.style.left = '0'
    textArea.style.position = 'fixed'
    textArea.style.opacity = '0'
    textArea.style.pointerEvents = 'none'
    textArea.style.userSelect = 'text'
    textArea.style.webkitUserSelect = 'text'
    textArea.setAttribute('readonly', '')
    
    document.body.appendChild(textArea)
    
    let success = false
    let errorType = 'unknown'
    
    try {
      textArea.focus()
      textArea.select()
      textArea.setSelectionRange(0, text.length)
      
      success = document.execCommand('copy')
      
      if (!success) {
        errorType = 'execCommand_failed'
      }
    } catch (err) {
      console.error('降级复制失败:', err)
      errorType = 'execCommand_error'
    } finally {
      document.body.removeChild(textArea)
    }
    
    return { success, error: success ? null : errorType }
  }

  /**
   * 获取用户友好的错误消息
   * @param {string} errorType - 错误类型
   * @param {string} text - 要复制的文本
   * @returns {Object} - 包含消息和建议的对象
   */
  const getFriendlyErrorMessage = (errorType, text) => {
    const messages = {
      permission: {
        message: '浏览器阻止了复制操作',
        suggestion: '请允许网站访问剪贴板，或手动复制文本',
        action: 'retry'
      },
      unsupported: {
        message: '您的浏览器不支持自动复制',
        suggestion: `请手动复制：${text}`,
        action: 'manual'
      },
      data: {
        message: '复制的内容格式有误',
        suggestion: '请重试或手动复制',
        action: 'retry'
      },
      execCommand_failed: {
        message: '复制功能暂时不可用',
        suggestion: `请手动复制：${text}`,
        action: 'manual'
      },
      execCommand_error: {
        message: '复制操作被阻止',
        suggestion: '请手动选择并复制文本',
        action: 'manual'
      },
      unknown: {
        message: '复制失败',
        suggestion: `请手动复制：${text}`,
        action: 'manual'
      }
    }
    
    return messages[errorType] || messages.unknown
  }

  /**
   * 重试复制操作
   * @param {string} text - 要复制的文本
   * @param {Object} options - 配置选项
   * @returns {Promise<boolean>} - 复制是否成功
   */
  const retryCopy = async (text, options = {}) => {
    if (isRetrying.value) {
      return false
    }
    
    isRetrying.value = true
    
    try {
      // 等待一小段时间再重试
      await new Promise(resolve => setTimeout(resolve, 500))
      const result = await copyToClipboard(text, { ...options, isRetry: true })
      return result
    } finally {
      isRetrying.value = false
    }
  }

  /**
   * 复制文本到剪贴板
   * 优先使用现代 Clipboard API，失败时使用降级方案
   * @param {string} text - 要复制的文本
   * @param {Object} options - 配置选项
   * @param {string} options.successMessage - 成功时的提示消息
   * @param {string} options.errorMessage - 失败时的提示消息
   * @param {number} options.toastDuration - toast 显示持续时间
   * @param {boolean} options.showToast - 是否显示 toast 提示
   * @param {boolean} options.enableRetry - 是否启用重试功能
   * @param {boolean} options.isRetry - 是否为重试操作
   * @returns {Promise<boolean>} - 复制是否成功
   */
  const copyToClipboard = async (text, options = {}) => {
    const {
      successMessage = '复制成功！',
      errorMessage = '复制失败，请手动复制',
      toastDuration = 2000,
      showToast: shouldShowToast = true,
      enableRetry = true,
      isRetry = false
    } = options

    // 验证输入
    if (!text || typeof text !== 'string') {
      console.warn('复制的文本不能为空或格式不正确')
      if (shouldShowToast) {
        showToastMessage('复制内容无效', toastDuration, 'warning')
      }
      return false
    }

    // 记录复制尝试
    lastCopyAttempt.value = {
      text,
      timestamp: Date.now(),
      isRetry
    }

    let result = { success: false, error: 'unknown' }

    // 优先使用现代 Clipboard API
    if (navigator.clipboard && window.isSecureContext) {
      result = await copyWithClipboardAPI(text)
    }

    // 如果现代 API 失败，使用降级方案
    if (!result.success) {
      result = fallbackCopyTextToClipboard(text)
    }

    // 处理结果和用户反馈
    if (shouldShowToast) {
      if (result.success) {
        showToastMessage(successMessage, toastDuration, 'success')
      } else {
        const errorInfo = getFriendlyErrorMessage(result.error, text)
        const message = isRetry ? `重试失败：${errorInfo.message}` : errorInfo.message
        
        // 根据错误类型显示不同的提示
        if (errorInfo.action === 'retry' && enableRetry && !isRetry) {
          showToastMessage(`${message}，点击重试`, toastDuration * 1.5, 'error')
        } else {
          showToastMessage(`${message}\n${errorInfo.suggestion}`, toastDuration * 2, 'error')
        }
      }
    }

    return result.success
  }

  /**
   * 检查是否支持剪贴板功能
   * @returns {Object} - 支持情况的详细信息
   */
  const getClipboardSupport = () => {
    const hasClipboardAPI = !!(navigator.clipboard && window.isSecureContext)
    const hasExecCommand = !!document.execCommand
    const isSupported = hasClipboardAPI || hasExecCommand
    
    return {
      hasClipboardAPI,
      hasExecCommand,
      isSupported,
      isSecureContext: window.isSecureContext,
      userAgent: navigator.userAgent,
      recommendedMethod: hasClipboardAPI ? 'clipboard' : hasExecCommand ? 'execCommand' : 'manual'
    }
  }

  /**
   * 获取复制功能的诊断信息
   * @returns {Object} - 诊断信息
   */
  const getDiagnosticInfo = () => {
    const support = getClipboardSupport()
    return {
      ...support,
      lastAttempt: lastCopyAttempt.value,
      isRetrying: isRetrying.value,
      timestamp: Date.now()
    }
  }

  return {
    // 响应式状态
    showToast,
    toastMessage,
    toastType,
    isRetrying,
    lastCopyAttempt,
    
    // 方法
    copyToClipboard,
    retryCopy,
    showToastMessage,
    getClipboardSupport,
    getDiagnosticInfo,
    getFriendlyErrorMessage
  }
}

// 默认导出，方便直接导入
export default useCopy